﻿#include "DataProcessor.h"
#include <iomanip>
#include <QImage>
#include <QDir>
#include <QTextStream>
#include <QFileInfo>
#include <QPixmap>
#include <QImageWriter>

#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>


//1.文件解析（公有）
bool DataProcessor::readFile(const int type) {
	switch (type) {
	case 1:
		return read_image_to_map();
	case 2:
		return read_post();
	case 3:
		return read_txt_to_map();
	case 11:
		return read_map_routing_res();
	default:
		return false;
	}
	return false;
}
bool DataProcessor::readFile(string fullFileName, const int type) {
	m_qFullFileName = QString::fromStdString(fullFileName);
	QFileInfo fileInfo(m_qFullFileName);
	m_qFilePath = fileInfo.absolutePath();
	m_qFileName = fileInfo.fileName();
	if (m_data->maxPt.x() < 0 || m_data->maxPt.y() < 0) {
		std::cerr << "minPt and maxPt haven't been init!" << std::endl;
	}
	return readFile(type);
}
bool DataProcessor::readFile(QString qFullFileName, const int type) {
	m_qFullFileName = qFullFileName;
	QFileInfo fileInfo(qFullFileName);
	m_qFilePath = fileInfo.absolutePath();
	m_qFileName = fileInfo.fileName();
	return readFile(type);
}
//辅助私有函数
bool DataProcessor::read_post() {
	string fullPath = m_qFullFileName.toStdString();
	ifstream file(fullPath);//this->filePath_ + "/" + this->fileName_
	if (file.fail())
		return false;
	string line;
	vector<vector<numbers>> wireCoordinates;
	vector<vector<vector<numbers>>> obsCoordinates;
	vector<vector<numbers>> fixlinesCoordinates;
	vector<vector<numbers>> locklinesCoordinates;
	vector<vector<double>> gapCoordinates;
	vector<vector<double>> spacesCoordinate;
	vector<int> diffInfo_dirsCoordinates;
	bool inPoints = false;
	bool inWire = false;
	bool inObss = false;
	bool inFixLines = false;
	bool inLockLines = false;
	bool inGap = false;
	bool inSpaces = false;
	bool inOther = false;
	bool in_diffInfo_dir = false;
	while (getline(file, line)) {
		// 如果获取到的行没有数据，是空行，则跳过
		if (line.empty())
			continue;
		if (isSymbol(line, pointSymbol)) {
			inPoints = true;
			inWire = false;
			inObss = false;
			inFixLines = false;
			inLockLines = false;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = false;
			continue;
		}
		else if (isSymbol(line, wiresSymbol)) {
			inPoints = false;
			inWire = true;
			inObss = false;
			inFixLines = false;
			inLockLines = false;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = false;
			wireCoordinates.push_back(vector<numbers>());
			continue;
		}
		else if (isSymbol(line, obss_Symbol)) {
			inPoints = false;
			inWire = false;
			inObss = true;
			inFixLines = false;
			inLockLines = false;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = false;
			if (obsCoordinates.size() < wireCoordinates.size() || obsCoordinates.size() == 0) {
				obsCoordinates.push_back(vector<vector<numbers>>());
			}
			obsCoordinates.back().push_back(vector<numbers>());
			continue;
		}
		else if (isSymbol(line, miterSymbol)) {
			inPoints = false;
			inWire = false;
			inObss = false;
			inFixLines = false;
			inLockLines = false;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = false;
			continue;
		}
		else if (isSymbol(line, fixLiSymbol)) {
			inPoints = false;
			inWire = false;
			inObss = false;
			inFixLines = true;
			inLockLines = false;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = false;
			fixlinesCoordinates.push_back(vector<numbers>());
			continue;
		}
		else if (isSymbol(line, lockLSymbol)) {
			inPoints = false;
			inWire = false;
			inObss = false;
			inFixLines = false;
			inLockLines = true;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = false;
			locklinesCoordinates.push_back(vector<numbers>());
			continue;

		}
		else if (isSymbol(line, diGapSymbol)) {
			inPoints = false;
			inWire = false;
			inObss = false;
			inFixLines = false;
			inLockLines = false;
			inGap = true;
			inSpaces = false;
			in_diffInfo_dir = false;
			inOther = false;
			gapCoordinates.push_back(vector<double>());
			continue;
		}
		else if (isSymbol(line, spcssSymbol)) {
			inPoints = false;
			inWire = false;
			inObss = false;
			inFixLines = false;
			inLockLines = false;
			inGap = false;
			inSpaces = true;
			in_diffInfo_dir = false;
			inOther = false;
			spacesCoordinate.push_back(vector<double>());
			continue;
		}
		else if (isSymbol(line, diDirSymbol)) {
			inPoints = false;
			inWire = false;
			inObss = false;
			inFixLines = false;
			inLockLines = false;
			inGap = false;
			inSpaces = false;
			in_diffInfo_dir = true;
			inOther = false;
			continue;
		}
		else if (line.find("#") == 0) {
			continue;
		}
		numbers nums;
		if (inPoints) {
			int result = sscanf_s(line.c_str(), "%lf %lf %lf %lf %lf", &nums.num1, &nums.num2, &nums.num3, &nums.num4, &nums.num5);
			if (result != 2) {
				cout << "Error: the sum of numbers is not a 2D point" << line << endl;
			}
			m_data->m_Pts.push_back(QPointF(nums.num1, nums.num2));
		}
		else if (inWire) {
			int result = 0;
			if (line.find("0(Pt") == 0) {
				result = sscanf_s(line.c_str(), "%*d(Pt1 %lf %lf)(Pt2 %lf %lf)(width %lf)", &nums.num1, &nums.num2, &nums.num3, &nums.num4, &nums.num5);
			}
			else {
				result = sscanf_s(line.c_str(), "%lf %lf %lf %lf %lf", &nums.num1, &nums.num2, &nums.num3, &nums.num4, &nums.num5);
			}
			if (result == 4)
				nums.num5 = defaltWidth_;
			if (result >= 4) {
				wireCoordinates.back().push_back(nums);
			}
			else {
				continue;
			}
		}
		else if (inObss) {
			int result = 0;
			if (line.find("0(Pt") == 0) {
				result = sscanf_s(line.c_str(), "%*d(Pt1 %lf %lf)(Pt2 %lf %lf)", &nums.num1, &nums.num2, &nums.num3, &nums.num4);
			}
			else {
				result = sscanf_s(line.c_str(), "%lf %lf %lf %lf", &nums.num1, &nums.num2, &nums.num3, &nums.num4);
			}
			if (result >= 4) {
				obsCoordinates.back().back().push_back(nums);
			}
			else {
				continue;
			}
		}
		else if (inFixLines) {
			int result = 0;
			if (line.find("0(Pt") == 0) {
				result = sscanf_s(line.c_str(), "%*d(Pt1 %lf %lf)(Pt2 %lf %lf)", &nums.num1, &nums.num2, &nums.num3, &nums.num4);
			}
			else {
				result = sscanf_s(line.c_str(), "%lf %lf %lf %lf", &nums.num1, &nums.num2, &nums.num3, &nums.num4);
			}
			if (result >= 4) {
				fixlinesCoordinates.back().push_back(nums);
			}
			else {
				continue;
			}
		}
		else if (inLockLines) {
			int result = 0;
			if (line.find("0(Pt") == 0) {
				result = sscanf_s(line.c_str(), "%*d(Pt1 %lf %lf)(Pt2 %lf %lf)", &nums.num1, &nums.num2, &nums.num3, &nums.num4);
			}
			else {
				result = sscanf_s(line.c_str(), "%lf %lf %lf %lf", &nums.num1, &nums.num2, &nums.num3, &nums.num4);
			}
			if (result >= 4) {
				locklinesCoordinates.back().push_back(nums);
			}
			else {
				continue;
			}
		}
		else if (inGap) {
			int result = 0;
			double value = 1.0;
			result = sscanf_s(line.c_str(), "%lf", &value);
			if (result == 1) {
				gapCoordinates.back().push_back(value);
			}
		}
		else if (inSpaces) {
			int result = 0;
			double value = 1.0;
			result = sscanf_s(line.c_str(), "%lf", &value);
			if (result == 1) {
				spacesCoordinate.back().push_back(value);
			}
		}
		else if (in_diffInfo_dir) {
			int result = 0;
			int value = 1;
			result = sscanf_s(line.c_str(), "%d", &value);
			if (result == 1) {
				diffInfo_dirsCoordinates.push_back(value);
			}
		}
		// 如果读取完了一组后处理数据，但是该组数据缺少一些数据，为了每组数据的完整性，需要将其余数据赋默认值
		fillBlankData(wireCoordinates, obsCoordinates, fixlinesCoordinates, locklinesCoordinates, gapCoordinates, spacesCoordinate, diffInfo_dirsCoordinates, 1);
	}
	int wireSize = (int)wireCoordinates.size();
	while (wireCoordinates.size() < wireSize || obsCoordinates.size() < wireSize || fixlinesCoordinates.size() < wireSize || locklinesCoordinates.size() < wireSize
		|| gapCoordinates.size() < wireSize || spacesCoordinate.size() < wireSize || diffInfo_dirsCoordinates.size() < wireSize) {
		fillBlankData(wireCoordinates, obsCoordinates, fixlinesCoordinates, locklinesCoordinates, gapCoordinates, spacesCoordinate, diffInfo_dirsCoordinates, 0);
	}
	file.close();
	// hugSegments_数据赋值
	for (const auto& one_wire : wireCoordinates) {
		if (one_wire.empty())
			break;
		m_data->m_wires.emplace_back(vector<LineUI>());
		for (const auto& nums : one_wire) {
			setMinMax(nums);
			LineUI line(QPointF(nums.num1, nums.num2), QPointF(nums.num3, nums.num4));
			line.width = nums.num5;
			m_data->m_wires.back().push_back(line);

		}
	}

	// Obs数据赋值
	for (const auto& obss : obsCoordinates) {
		m_data->m_polygonss.emplace_back(vector<vector<LineUI>>());
		for (const auto& obs : obss) {
			m_data->m_polygonss.back().emplace_back(vector<LineUI>());
			if (obs.empty()) continue;
			double minx = obs.front().num1, miny = obs.front().num2;
			double maxx = minx, maxy = miny;
			for (const auto& nums : obs) {
				setMinMax(nums);
				m_data->m_polygonss.back().back().emplace_back(LineUI(QPointF(nums.num1, nums.num2), QPointF(nums.num3, nums.num4)));
				minx = min(minx, min(nums.num1, nums.num3));
				miny = min(miny, min(nums.num2, nums.num4));
				maxx = max(maxx, max(nums.num1, nums.num3));
				maxy = max(maxy, max(nums.num2, nums.num4));
			}
			m_data->obssMinMaxXY.push_back({ minx, maxx, miny, maxy });
		}
	}
	// fixLines_数据赋值
	for (const auto& one_fixline : fixlinesCoordinates) {
		m_data->fixLines_.push_back(vector<LineUI>());
		if (one_fixline.empty()) continue;
		for (const auto& nums : one_fixline) {
			m_data->fixLines_.back().push_back(LineUI(QPointF(nums.num1, nums.num2), QPointF(nums.num3, nums.num4)));
		}
	}
	// lockLines_数据赋值
	for (const auto& one_lockline : locklinesCoordinates) {
		m_data->lockLines_.push_back(vector<LineUI>());
		if (one_lockline.empty()) continue;
		for (const auto& nums : one_lockline) {
			m_data->lockLines_.back().push_back(LineUI(QPointF(nums.num1, nums.num2), QPointF(nums.num3, nums.num4)));
		}
	}
	// diffGaps_数据赋值
	for (const auto& one_gap : gapCoordinates) {
		m_data->diffGaps_.push_back(vector<double>());
		if (one_gap.empty()) continue;
		for (const auto& gap : one_gap) {
			m_data->diffGaps_.back().push_back(gap);
		}
	}
	//spaces数据赋值
	for (const auto& one_space : spacesCoordinate) {
		m_data->spaces_.push_back(vector<double>());
		if (one_space.empty()) continue;
		for (const auto& space : one_space) {
			m_data->spaces_.back().push_back(space);
		}
	}
	// diffInfo_dirs数据赋值
	for (const auto& dir : diffInfo_dirsCoordinates) {
		int dir_side = dir == 2010 ? 2 : dir;
		m_data->diffInfo_dirs.push_back(dir_side);
	}
	return true;
}
bool DataProcessor::read_txt_to_map() {
	QFile qTxtFile(m_qFullFileName);
	if (!qTxtFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
		qWarning() << "Failed to open txt file! ";
		return false;
	}
	vector<numbers> pinCoordinates;
	QTextStream in(&qTxtFile);
	bool in_start_end = false;
	bool in_map = false;
	bool in_others = false;
	int x = 0, y = 0;
	while (!in.atEnd()) {
		QString line = in.readLine().trimmed();
		if (line.isEmpty()) continue;  // 跳过空行
		if (line.startsWith("$ST")) {
			in_start_end = true;
			in_map = false;
			in_others = false;
			continue;
		}
		else if (line.startsWith("$Map")) {
			y = 0;
			in_start_end = false;
			in_map = true;
			in_others = false;
			continue;
		}
		else if (line.startsWith("$")) {  // 未知的数据标记
			in_start_end = false;
			in_map = false;
			in_others = true;
			continue;
		}
		QTextStream lineStream(&line);
		numbers nums;
		if (in_start_end) {
			lineStream >> nums.num1 >> nums.num2 >> nums.num3 >> nums.num4;
			if (lineStream.status() == QTextStream::Ok) {
				pinCoordinates.push_back(nums);
			}
		}
		else if (in_map) {
			m_data->m_mapSymbols.emplace_back(line);
			for (x = 0; x < line.size(); ++x) {
				if (line[x] == '#')
					m_data->m_Pts.emplace_back(QPointF(x, y));
			}
			y++;
		}
		else if (in_others) {
			continue;
		}
	}
	qTxtFile.close();
	//m_data赋值
	//维护m_data中的数据
		//1.维护飞线
	for (auto& nums : pinCoordinates) {
		m_data->m_flyLines.emplace_back(LineUI(nums.num2, nums.num1, nums.num4, nums.num3));
	}
	//维护地图字符（在读取时维护）
	m_data->minPt = QPointF(0, 0);
	m_data->maxPt = QPointF(x, y);
	m_data->m_net.emplace_back(vector<LineUI>());
	m_data->m_net.emplace_back(vector<LineUI>());
	for (int i = 0; i < m_data->maxPt.x(); i++) {  //竖线（x轴为水平方向）
		m_data->m_net[0].emplace_back(LineUI(i, 0, i, m_data->maxPt.y() - 1));
	}
	for (int i = 0; i < m_data->maxPt.y(); i++) {
		m_data->m_net[1].emplace_back(LineUI(0, i, m_data->maxPt.x() - 1, i));
	}
	return true;
}
bool DataProcessor::read_image_to_map() {
	QFileInfo fileInfo(m_qFileName);
	QString txtName = fileInfo.baseName() + ".txt";
	QString txtFullName = m_qFilePath + "/" + txtName;
	QImage image(m_qFullFileName);
	if (image.isNull()) {
		std::cerr << "Picture can't be open!" << std::endl;
		return false;
	}
	QFile outputFile(txtFullName);
	if (!outputFile.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) {
		std::cerr << "Text file can't be created!" << std::endl;
		return false;
	}
	QTextStream out(&outputFile);
	// 写入起点终点
	out << "$ST \n";
	//pin对（即飞线）,传入整数4代表随机pin数量，0代表自动数量
	m_data->m_flyLines = getRandomPts(image.width(), image.height(), m_data->m_pinSum);
	for (auto& lineui : m_data->m_flyLines) {
		out << lineui.p1().y() << ' '  // 直接输出数值，避免中间字符串
			<< lineui.p1().x() << ' '
			<< lineui.p2().y() << ' '
			<< lineui.p2().x() << '\n';
	}

	out << "$Map \n";
	for (int y = 0; y < image.height(); ++y) {
		m_data->m_mapSymbols.emplace_back(QString());
		for (int x = 0; x < image.width(); ++x) {
			QRgb pixel = image.pixel(x, y);
			int red = qRed(pixel);
			int green = qGreen(pixel);
			int blue = qBlue(pixel);
			int alpha = qAlpha(pixel);
			if (red == 255 && green == 255 && blue == 255 && alpha == 255) {
				m_data->m_mapSymbols.back() += 'o';
				out << "o";
			}
			else {
				m_data->m_mapSymbols.back() += '#';
				m_data->m_Pts.emplace_back(QPointF(x, y));
				out << "#";
			}
		}
		out << '\n';
	}
	outputFile.close();
	//m_data赋值
	m_data->minPt = QPointF(0, 0);
	m_data->maxPt = QPointF((int)image.width(), (int)image.height());
	m_data->m_net.emplace_back(vector<LineUI>());
	m_data->m_net.emplace_back(vector<LineUI>());
	for (int i = 0; i < m_data->maxPt.x(); i++) {  //竖线（x轴为水平方向）
		m_data->m_net[0].emplace_back(LineUI(i, 0, i, m_data->maxPt.y() - 1));
	}
	for (int i = 0; i < m_data->maxPt.y(); i++) {
		m_data->m_net[1].emplace_back(LineUI(0, i, m_data->maxPt.x() - 1, i));
	}
	return true;
}

bool DataProcessor::read_map_routing_res() {
	// 1. 读取文件
	QFile file(m_qFullFileName);
	if (!file.open(QIODevice::ReadOnly)) {
		qWarning() << "无法打开文件:" << m_qFullFileName;
		return false;
	}

	QByteArray data = file.readAll();
	file.close();

	// 2. 解析 JSON
	QJsonDocument doc = QJsonDocument::fromJson(data);
	if (doc.isNull()) {
		qWarning() << "无效的 JSON 格式";
		return false;
	}

	QJsonObject root = doc.object();

	// 3. 提取 map_size
	QJsonArray mapSize = root["map_size"].toArray();
	int height = mapSize[0].toInt();
	int width = mapSize[1].toInt();
	m_data->minPt = QPointF(0, 0);
	m_data->maxPt = QPointF((int)width, (int)height);
	m_data->m_net.emplace_back(vector<LineUI>());
	m_data->m_net.emplace_back(vector<LineUI>());
	for (int i = 0; i < width; i++) {	//竖线（x轴为水平方向）
		m_data->m_net[0].emplace_back(LineUI(i, 0, i, height - 1));
	}
	for (int i = 0; i < height; i++) {
		m_data->m_net[1].emplace_back(LineUI(0, i, width - 1, i));
	}
	// 4. 提取 pins
	for (const QJsonValue& pinVal : root["pins"].toArray()) {
		QJsonArray onePin = pinVal.toArray();
		int num1 = onePin[0].toInt();
		int num2 = onePin[1].toInt();
		int num4 = onePin[3].toInt();
		int num5 = onePin[4].toInt();
		m_data->m_flyLines.emplace_back(LineUI(num2, num1, num5, num4));
	}

	// 5. 提取 prePath
	for (const QString& key : root["prePath"].toObject().keys()) {
		m_data->m_wiresPts.emplace_back(vector<QPointF>());
		for (const QJsonValue& pointVal : root["prePath"].toObject()[key].toArray()) {
			QJsonArray pt = pointVal.toArray();
			int num1 = pointVal[0].toInt();
			int num2 = pointVal[1].toInt();
			m_data->m_wiresPts.back().emplace_back(QPointF(num2, num1));
		}
	}

	// 6. 提取 resPath
	for (const QString& key : root["resPath"].toObject().keys()) {
		m_data->m_resWiresPts.emplace_back(vector<QPointF>());
		for (const QJsonValue& pointVal : root["resPath"].toObject()[key].toArray()) {
			QJsonArray pt = pointVal.toArray();
			int num1 = pointVal[0].toInt();
			int num2 = pointVal[1].toInt();
			m_data->m_resWiresPts.back().emplace_back(QPointF(num2, num1));
		}
	}

	// 7. 提取 map 数据
	QVector<QVector<QVector<int>>> mapData;
	for (const QJsonValue& rows : root["map"].toArray()) {
		for (const QJsonValue& pt_json : rows.toArray()) {
			QJsonArray pt = pt_json.toArray();	//x，y,layer,obs
			int num1 = pt[0].toInt();
			int num2 = pt[1].toInt();
			int num4 = pt[3].toInt();
			if (num4 == 1) {		//是障碍物
				m_data->m_Pts.emplace_back(QPointF(num2, num1));
			}
		}
	}
	return true;
}

void DataProcessor::setMinMax(const numbers& nums) {
	// 获取最大最小的数字，存入minNumX, minNumY, maxNumX, maxNumY中
	if (m_data->minPt.x() < 0 && m_data->minPt.y() < 0 && m_data->maxPt.x() < 0 && m_data->maxPt.y() < 0) {  //初始化
		m_data->minPt.setX(isnan(nums.num1) ? m_data->minPt.x() : nums.num1);
		m_data->minPt.setY(isnan(nums.num2) ? m_data->minPt.y() : nums.num2);
		m_data->maxPt.setX(isnan(nums.num3) ? m_data->maxPt.x() : nums.num3);
		m_data->maxPt.setY(isnan(nums.num4) ? m_data->maxPt.y() : nums.num4);
	}
	else {
		double num13 = min(nums.num1, nums.num3);
		double num24 = min(nums.num2, nums.num4);
		num13 = isnan(num13) ? m_data->minPt.x() : num13;
		num24 = isnan(num24) ? m_data->minPt.y() : num24;
		m_data->minPt.setX(min(m_data->minPt.x(), num13));
		m_data->minPt.setY(min(m_data->minPt.y(), num24));

		num13 = max(nums.num1, nums.num3);
		num24 = max(nums.num2, nums.num4);
		num13 = isnan(num13) ? m_data->maxPt.x() : num13;
		num24 = isnan(num24) ? m_data->maxPt.y() : num24;
		m_data->maxPt.setX(max(m_data->maxPt.x(), num13));
		m_data->maxPt.setY(max(m_data->maxPt.y(), num24));
	}
}
void DataProcessor::fillBlankData(vector<vector<numbers>>& wireCoordinates,
	vector<vector<vector<numbers>>>& obsCoordinates,
	vector<vector<numbers>>& fixlinesCoordinates,
	vector<vector<numbers>>& locklinesCoordinates,
	vector<vector<double>>& gapCoordinates,
	vector<vector<double>>& spacesCoordinate,
	vector<int>& diffInfo_dirsCoordinates, int add) {
	// add = 1，表示在读取数据内部，add = 0表示已经完成所有数据的读取
	if ((int)obsCoordinates.size() < (int)wireCoordinates.size() - add) {				// 1.补全obs
		obsCoordinates.emplace_back(vector<vector<numbers>>());
	}
	if ((int)fixlinesCoordinates.size() < (int)wireCoordinates.size() - add) {			// 2.补全fixlines
		fixlinesCoordinates.emplace_back(vector<numbers>());
	}
	if ((int)locklinesCoordinates.size() < (int)wireCoordinates.size() - add) {			// 3.补全locklines
		locklinesCoordinates.emplace_back(vector<numbers>());
	}
	if ((int)gapCoordinates.size() < (int)wireCoordinates.size() - add) {				// 4.补全gaps
		gapCoordinates.emplace_back(vector<double>());
	}
	if ((int)spacesCoordinate.size() < (int)wireCoordinates.size() - add) {				// 5.补全spaces
		spacesCoordinate.emplace_back(vector<double>());
	}
	if ((int)diffInfo_dirsCoordinates.size() < (int)wireCoordinates.size() - add) {		// 6.补全diffInfo_dirsCoordinates
		diffInfo_dirsCoordinates.emplace_back(2010);
	}
}

//2.数据处理（公有）
vector<LineUI> DataProcessor::getRandomPts(int width, int height, int randPtSum) {	// 计算前端读取图片作为地图时,生成txt地图文件,写入的起点终点坐标
	// 参数width表示图片的宽度,height表示图片的高度
	bool left_begin_right_end = false;	// 起点终点在两侧
	int pin_sum = height / 50 + 3;	// 生成pin的数量，默认图片高度的1/100+1：height / 100 + 1
	if (width > 200) {
		pin_sum = 8;
	}
	int left_max_dist = width;
	if (left_begin_right_end) {
		if (width < 201)
			left_max_dist = 20;
		else if (width < 501)
			left_max_dist = 40;
		else if (width < 1001)
			left_max_dist = 80;
		else if (width < 2001)
			left_max_dist = 160;
		else if (width < 4001)
			left_max_dist = 320;
	}
	if (randPtSum >= 0) pin_sum = randPtSum;
	std::vector<LineUI> result;
	for (int i = 0; i < pin_sum; i++) {
		// x取随机数，y取两侧附近的随机数
		int pt1x = rand() % left_max_dist;
		int pt1y = rand() % height;
		int pt2x = width - left_max_dist + rand() % left_max_dist;
		int pt2y = rand() % height;
		result.emplace_back(LineUI(pt1x, pt1y, pt2x, pt2y));		//写入basicData对象中
	}
	return result;
}
//2.2设置线段上所有整数点
void DataProcessor::setPtsFromLines(vector<LineUI>& lines, vector<QPointF>& pts) {
	pts.clear();
	int len = lines.size();
	if (len > 0) {
		if (lines[0].length() > 2000)	return;		//线段实际长度过大，不进行整数点设置
		pts = lines[0].getIntPts(true, true);
	}
	for (int i = 1; i < len; ++i) {
		vector<QPointF> one_line_pts = lines[i].getIntPts(false, true);
		pts.insert(pts.end(), one_line_pts.begin(), one_line_pts.end());
	}
}
void DataProcessor::setPtsFromLines(vector<vector<LineUI>>& liness, vector<vector<QPointF>>& pts) {
	pts.clear();
	for (auto& lines : liness) {
		pts.emplace_back(vector<QPointF>());
		setPtsFromLines(lines, pts.back());
	}
}
void DataProcessor::setLengths(vector<vector<LineUI>>& liness, TYPE type) {
	vector<vector<double>>* lineLengths = nullptr;
	if (type == PRE_LINE) {
		preLineLengths_.clear();
		lineLengths = &preLineLengths_;
	}
	else if (type == POST_LINE) {
		postLineLengths_.clear();
		lineLengths = &postLineLengths_;
	}
	for (auto& lines : liness) {
		lineLengths->emplace_back(vector<double>());
		for (auto& line : lines) {
			double length = line.length();
			lineLengths->back().emplace_back(length);
		}
	}

}
void DataProcessor::data_clear(bool readdata_clear) {	// 默认需要清理读取的数据
	// 读取的数据
	if (readdata_clear) {
		;
	}
	// 算法执行获得的数据
	;
}

//3.文件输出（公有）

bool DataProcessor::write_PPDT_case() {
	return true;
}
bool DataProcessor::write_PPDT_Pre(const QString& qFullName, const vector<LineUI>& pinPairs,
	const vector<vector<QPointF>>& pathPts, const vector<QString>& mapSymbols) {
	//新建一个文件，覆盖写入map_size，pins，prePath
	QFile outputFile(qFullName);
	if (!outputFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
		qDebug() << "无法打开输出文件:" << qFullName;
		return false;
	}
	QTextStream out(&outputFile);
	out.setEncoding(QStringConverter::Utf8); // 设置编码为 UTF-8

	// 使用 QTextStream 写入，保持与原来完全相同的格式
	out << "{\n"; // 外层括号===========================================================================

	// 1.写入map_size
	if (mapSymbols.empty() || mapSymbols[0].isEmpty()) {
		qDebug() << "m_data->m_mapSymbols(地图字符表)为空";
		outputFile.close();
		return false;
	}
	out << "  \"map_size\": [" << mapSymbols.size() << ", " << mapSymbols[0].size() << "],\n";

	// 2.写入 m_Pins
	out << "  \"pins\": [\n"; // "pins"键开始
	for (size_t i = 0; i < pinPairs.size(); ++i) {
		out << "    ["; // 单个pin数组开始
		out << pinPairs[i].p1().y() << ", " << pinPairs[i].p1().x() << ", " << 0 << ", "; // start的x, y, l
		out << pinPairs[i].p2().y() << ", " << pinPairs[i].p2().x() << ", " << 0; // end的x, y, l
		if (i < pinPairs.size() - 1) {
			out << "],\n"; // 非最后一个pin，添加逗号
		}
		else {
			out << "]\n"; // 最后一个pin，不添加逗号
		}
	}
	out << "  ],\n"; // "pins"键结束

	// 3.写入prePath
	out << "  \"prePath\": {\n"; // "path"键开始
	for (size_t i = 0; i < pathPts.size(); ++i) {
		out << "    \"" << i << "\": [\n"; // 路径键开始
		for (size_t j = 0; j < pathPts[i].size(); ++j) {
			out << "      [" << pathPts[i][j].y() << ", " << pathPts[i][j].x() << "]";
			if (j < pathPts[i].size() - 1) {
				out << ",\n"; // 非最后一行，添加逗号
			}
			else {
				out << "\n"; // 最后一行，不添加逗号
			}
		}
		if (i < pathPts.size() - 1) {
			out << "    ],\n"; // 非最后一条路径，添加逗号
		}
		else {
			out << "    ]\n"; // 最后一条路径，不添加逗号
		}
	}
	out << "  },\n"; // "prePath"键结束
	outputFile.close();
	return true;
}

bool DataProcessor::write_PPDT_Res(const QString& qFullName, const vector<vector<QPointF>>& pathPts, const vector<QString>& mapSymbols) {
	// 打开文件追加写入resPath和map
	QFile outputFile(qFullName);
	if (!outputFile.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Append)) {
		qDebug() << "无法打开输出文件:" << qFullName;
		return false;
	}
	QTextStream out(&outputFile);
	out.setEncoding(QStringConverter::Utf8); // 设置编码为 UTF-8

	//4.写入resPath
	out << "  \"resPath\": {\n"; // "path"键开始
	for (size_t i = 0; i < pathPts.size(); ++i) {
		out << "    \"" << i << "\": [\n"; // 路径键开始
		for (size_t j = 0; j < pathPts[i].size(); ++j) {
			out << "      [" << pathPts[i][j].y() << ", " << pathPts[i][j].x() << "]";
			if (j < pathPts[i].size() - 1) {
				out << ",\n"; // 非最后一行，添加逗号
			}
			else {
				out << "\n"; // 最后一行，不添加逗号
			}
		}
		if (i < pathPts.size() - 1) {
			out << "    ],\n"; // 非最后一条路径，添加逗号
		}
		else {
			out << "    ]\n"; // 最后一条路径，不添加逗号
		}
	}
	out << "  },\n"; // "resPath"键结束

	//5.写入 map
	if (mapSymbols.empty() || mapSymbols[0].isEmpty()) {
		qDebug() << "m_data->m_mapSymbols(地图字符表)为空";
		outputFile.close();
		return false;
	}
	out << "  \"map\": [\n"; // "map"键开始
	for (size_t i = 0; i < mapSymbols.size(); ++i) {
		out << "    [\n"; // 单行地图数据开始
		for (size_t j = 0; j < mapSymbols[i].size(); ++j) {
			int symbol_int = mapSymbols[i][j] == '#' ? 1 : 0;
			out << "      [" << i << ", " << j << ", " << 0 << ", " << symbol_int << "]";
			if (j < mapSymbols[i].size() - 1) {
				out << ",\n"; // 非最后一个点，添加逗号
			}
			else {
				out << "\n"; // 最后一个点，不添加逗号
			}
		}
		if (i < mapSymbols.size() - 1) {
			out << "    ],\n"; // 非最后一行，添加逗号
		}
		else {
			out << "    ]\n"; // 最后一行，不添加逗号
		}
	}
	out << "  ]\n"; // "map"键结束
	out << "}\n";   // 外层括号外层括号===========================================================================
	outputFile.close();
	return true;
}
bool DataProcessor::writeOutputData(const QString& qFullName, vector<vector<LineUI>> liness) {
	//QFileInfo fileInfo(qFullName);
	//QString outputFileName = fileInfo.path() + "/" + fileInfo.completeBaseName() + "_af_post.txt";
	QFile outFile(qFullName);
	if (!outFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
		return false;
	}
	QTextStream outStream(&outFile);
	outStream.setRealNumberPrecision(6); // 设置统一精度
	for (const auto& outerPath : liness) {
		outStream << "#outputLine\n";
		for (const auto& line : outerPath) {
			double x1 = line.p1().x();
			double y1 = line.p1().y();
			double x2 = line.p2().x();
			double y2 = line.p2().y();

			// 判断是否为整数
			auto writeCoord = [&outStream](double val) {
				if (qAbs(val - qRound(val)) < 1e-6) {
					outStream << qRound(val);
				}
				else {
					outStream << val;
				}
				};
			outStream << "0(Pt1 ";
			writeCoord(x1);
			outStream << " ";
			writeCoord(y1);
			outStream << ")(Pt2 ";
			writeCoord(x2);
			outStream << " ";
			writeCoord(y2);
			outStream << ")\n";
		}
		outStream << "\n"; // 空行分隔
	}
	outFile.close();
	return true;
}
void DataProcessor::set_xy_swap() {
	x_horizontal = !x_horizontal;
}

//输出文件





